package InstanceZone

import (
	codecs "sanguo/codec/cs"
	"sanguo/node/common/com_type"
	"sanguo/node/common/transaction"
	"sanguo/node/node_game"
	"sanguo/node/node_game/module/role"
	"sanguo/node/node_game/user"
	table_BattleLevel "sanguo/node/table/excel/table/BattleLevel"
	table_Map "sanguo/node/table/excel/table/Map"
	cs_message "sanguo/protocol/cs/message"
	"time"

	"github.com/golang/protobuf/proto"
)

type transactionLeaveMap struct {
	transaction.TransactionBase
	user    *user.User
	req     *codecs.Message
	resp    *cs_message.LeaveMapToC
	errcode cs_message.EnumType
}

func (this *transactionLeaveMap) GetModuleName() string {
	return "InstanceZone"
}

func (this *transactionLeaveMap) GetReplyMsg() proto.Message {
	return &cs_message.LeaveMapToC{}
}

func (this *transactionLeaveMap) SetExpiredTime(expired time.Time) {
	this.Expired = expired
}

func (this *transactionLeaveMap) GetExpiredTime() time.Time {
	return this.Expired
}

func (this *transactionLeaveMap) Begin() {
	this.resp = &cs_message.LeaveMapToC{}
	msg := this.req.GetData().(*cs_message.LeaveMapToS)
	roleModule := this.user.GetModuleByName("role").(*role.RoleModule)
	role := roleModule.CurrentRole()
	if nil == role || !role.IsRoleModleData() {
		node_game.Infoln(this.user.GetUserID(), "LeaveMap fail : no selectRole ")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
	}
	node_game.Infof("%s %d Call LeaveMap mapId:%d ", role.GetUserID(), role.GetID(), msg.GetReqMapID())
	instanceZone := role.GetInstanceZone()
	if instanceZone == nil {
		node_game.Infoln(role.GetUserID(), role.GetID(), "fail instanceZone is  nil")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}

	if instanceZone.InitType == com_type.InstanceZone_Mission {
		//地图传送
		IZDef := table_BattleLevel.Table_.IDMap[instanceZone.ID]
		MapDef := table_Map.Table_.IDMap[msg.GetReqMapID()]
		if instanceZone.IsThroughOK && !IZDef.NeedTP && MapDef != nil {
			this.resp.MapID = proto.Int32(msg.GetReqMapID())
			this.resp.Position = &cs_message.Position{
				X: proto.Int32(msg.GetReqPosition().GetX()),
				Y: proto.Int32(msg.GetReqPosition().GetY()),
				Z: proto.Int32(msg.GetReqPosition().GetZ()),
			}
			this.resp.Angle = proto.Int32(msg.GetReqAngle())
			role.EnterMap(msg.GetReqMapID(), msg.ReqPosition.GetX(), msg.GetReqPosition().GetY(), msg.GetReqPosition().GetZ(), msg.GetReqAngle())
		} else {
			this.resp.MapID = proto.Int32(instanceZone.OldMapID)
			this.resp.Position = &cs_message.Position{
				X: proto.Int32(instanceZone.OldPosX),
				Y: proto.Int32(instanceZone.OldPosY),
				Z: proto.Int32(instanceZone.OldPosZ),
			}
			this.resp.Angle = proto.Int32(instanceZone.OldPosAngle)
			role.EnterMap(instanceZone.OldMapID, instanceZone.OldPosX, instanceZone.OldPosY, instanceZone.OldPosZ, instanceZone.OldPosAngle)
		}

		role.ClearInstanceZone()
	} else if instanceZone.InitType == com_type.InstanceZone_YhBattleGround {
		battleGound := role.GetBattleGround()
		if battleGound == nil {
			node_game.Infoln(role.GetUserID(), role.GetID(), "fail battleGound is  nil")
			this.errcode = cs_message.EnumType_ERROR
			this.user.EndTrans(this)
			return
		}
		this.resp.MapID = proto.Int32(battleGound.OldMapID)
		this.resp.Position = &cs_message.Position{
			X: proto.Int32(battleGound.OldPosX),
			Y: proto.Int32(battleGound.OldPosY),
			Z: proto.Int32(battleGound.OldPosZ),
		}
		this.resp.Angle = proto.Int32(battleGound.OldPosAngle)
		role.EnterMap(battleGound.OldMapID, battleGound.OldPosX, battleGound.OldPosY, battleGound.OldPosZ, battleGound.OldPosAngle)

		role.ClearInstanceZone()
		role.ClearBattleGround()
	} else if instanceZone.InitType == com_type.InstanceZone_Boss {
		this.resp.MapID = proto.Int32(instanceZone.OldMapID)
		this.resp.Position = &cs_message.Position{
			X: proto.Int32(instanceZone.OldPosX),
			Y: proto.Int32(instanceZone.OldPosY),
			Z: proto.Int32(instanceZone.OldPosZ),
		}
		this.resp.Angle = proto.Int32(instanceZone.OldPosAngle)
		role.EnterMap(instanceZone.OldMapID, instanceZone.OldPosX, instanceZone.OldPosY, instanceZone.OldPosZ, instanceZone.OldPosAngle)
		role.ClearInstanceZone()
	}

	node_game.Infoln(role.GetUserID(), role.GetID(), "battleLevel LeaveMap OK")
	this.errcode = cs_message.EnumType_OK
	this.user.EndTrans(this)
}

func (this *transactionLeaveMap) End() {
	this.resp.Errcode = cs_message.EnumType(this.errcode).Enum()
	this.user.Reply(this.req.GetSeriNo(), this.resp)
}

func (this *transactionLeaveMap) Timeout() {
	this.errcode = cs_message.EnumType_RETRY
	this.user.EndTrans(this)
}

func init() {
	user.RegisterTransFunc(&cs_message.LeaveMapToS{}, func(user *user.User, msg *codecs.Message) transaction.Transaction {
		return &transactionLeaveMap{
			user: user,
			req:  msg,
		}
	})
}
